<template>
  <div class="viewer-container">
    <div v-if="showWarning" class="warning-banner">
      <svg class="warning-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
        <line x1="12" y1="9" x2="12" y2="13"/>
        <line x1="12" y1="17" x2="12.01" y2="17"/>
      </svg>
      <span>检测到大容量内容 ({{ textSize }}). 性能可能会受到影响.</span>
    </div>
    
    <div class="content-wrapper">
      <div class="toolbar">
        <button @click="handleCopy" class="copy-button">
          <svg v-if="isCopying" class="copy-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor">
            <path d="M20 6L9 17l-5-5"/>
          </svg>
          <svg v-else class="copy-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor">
            <rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
            <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
          </svg>
        </button>
      </div>
      
      <pre class="content-pre" :style="{ maxHeight: `${maxHeight}px` }">{{ displayText }}</pre>
    </div>

    <button
      v-if="text.length > chunkSize"
      @click="toggleExpand"
      class="expand-button"
    >
      <svg 
        class="expand-icon"
        :class="{ expanded: isExpanded }"
        xmlns="http://www.w3.org/2000/svg" 
        viewBox="0 0 24 24" 
        fill="none" 
        stroke="currentColor"
      >
        <polyline points="6 9 12 15 18 9"/>
      </svg>
      {{ isExpanded ? 'Show less' : 'Show more' }}
    </button>
  </div>
</template>

<script>
export default {
  name: 'VirtualTextViewer',
  props: {
    text: {
      type: String,
      default: ''
    },
    maxHeight: {
      type: Number,
      default: 600
    }
  },
  
  data() {
    return {
      isExpanded: false,
      showWarning: false,
      isCopying: false,
      chunkSize: 1000,
      warningThreshold: 100000
    }
  },

  computed: {
    displayText() {
      if (!this.text) return ''
      return !this.isExpanded && this.text.length > this.chunkSize 
        ? this.text.slice(0, this.chunkSize) + '...'
        : this.text
    },

    textSize() {
      const bytes = new TextEncoder().encode(this.text).length
      if (bytes < 1024) return `${bytes} B`
      if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
      return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
    }
  },

  watch: {
    text: {
      immediate: true,
      handler(newText) {
        if (newText && newText.length > this.warningThreshold) {
          this.showWarning = true
        }
      }
    }
  },

  methods: {
    async handleCopy() {
      try {
        this.isCopying = true
        await navigator.clipboard.writeText(this.text)
        setTimeout(() => {
          this.isCopying = false
        }, 1000)
      } catch (err) {
        console.error('Failed to copy:', err)
        this.isCopying = false
      }
    },

    toggleExpand() {
      this.isExpanded = !this.isExpanded
    }
  }
}
</script>
<style scoped>
.viewer-container {
 background: white;
 border-radius: 0.5rem;
 box-shadow: 0 1px 2px rgba(0,0,0,0.05);
 border: 1px solid rgba(229,231,235,1);
}

.warning-banner {
 display: flex;
 align-items: center;
 gap: 0.75rem;
 padding: 0.75rem 1rem;
 margin-bottom: 1rem;
 background: rgb(254,243,199);
 color: rgb(146,64,14);
 border-radius: 0.5rem;
 border: 1px solid rgb(251,191,36);
}

.warning-icon {
 width: 1.25rem;
 height: 1.25rem;
 color: rgb(245,158,11);
 flex-shrink: 0;
}

.content-wrapper {
 position: relative;
 border-radius: 0.5rem;
 border: 1px solid rgba(229,231,235,0.75);
 transition: all 0.2s;
}

.toolbar {
 position: absolute;
 right: 0.75rem;
 top: 0.75rem;
 display: flex;
 gap: 0.5rem;
 z-index: 10;
}

.copy-button {
 padding: 0.5rem;
 color: rgb(107,114,128);
 background: rgba(255,255,255,0.9);
 backdrop-filter: blur(4px);
 border-radius: 0.375rem;
 transition: all 0.2s;
 box-shadow: 0 1px 2px rgba(0,0,0,0.05);
 border: 1px solid rgba(229,231,235,0.5);
}

.copy-button:hover {
 color: rgb(55,65,81);
 background: rgb(249,250,251);
 border-color: rgb(209,213,219);
}

.copy-icon {
 width: 1rem;
 height: 1rem;
 transition: transform 0.2s;
}

.content-pre {
 width: 100%;
 padding: 1.25rem;
 background: rgba(249,250,251,0.5);
 border-radius: 0.5rem;
 font-family: ui-monospace, monospace;
 font-size: 0.875rem;
 line-height: 1.625;
 color: rgb(55,65,81);
 overflow: auto;
 white-space: pre-wrap;
 backdrop-filter: blur(4px);
 transition: all 0.2s;
}

.expand-button {
 margin-top: 0.75rem;
 display: flex;
 align-items: center;
 gap: 0.5rem;
 padding: 0.375rem 0.75rem;
 font-size: 0.875rem;
 color: rgb(107,114,128);
 border-radius: 0.375rem;
 transition: all 0.2s;
 border: 1px solid rgba(229,231,235,0.5);
 width: fit-content;
}

.expand-button:hover {
 color: rgb(55,65,81);
 background: rgb(249,250,251);
 border-color: rgb(209,213,219);
}

.expand-icon {
 width: 1rem;
 height: 1rem;
 transition: transform 0.2s;
}

.expand-icon.expanded {
 transform: rotate(180deg);
}

/* Dark mode */
@media (prefers-color-scheme: dark) {
 .viewer-container {
   background: rgb(17,24,39);
   border-color: rgb(31,41,55);
 }

 .warning-banner {
   background: rgba(120,53,15,0.5);
   color: rgb(253,230,138);
   border-color: rgba(217,119,6,0.5);
 }

 .copy-button {
   background: rgba(17,24,39,0.9);
   border-color: rgba(55,65,81,0.5);
   color: rgb(156,163,175);
 }

 .copy-button:hover {
   background: rgb(31,41,55);
   border-color: rgb(75,85,99);
   color: rgb(209,213,219);
 }

 .content-pre {
   background: rgba(17,24,39,0.5);
   color: rgb(209,213,219);
   border-color: rgb(31,41,55);
 }

 .expand-button {
   color: rgb(156,163,175);
   border-color: rgba(55,65,81,0.5);
 }

 .expand-button:hover {
   color: rgb(209,213,219);
   background: rgba(31,41,55,0.5);
   border-color: rgb(75,85,99);
 }
}
</style>